package dyyx.buf;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;

public class ByteBufTest {
	
	
    // private static final ByteBufAllocator ALLOC = UnpooledByteBufAllocator.DEFAULT;

    private static final int INIT = 10;
    private static final int MAX = 32;

   
	public static void main(String[] args) throws Exception {
		
		
		// heap buf 
		ByteBuf buf = Unpooled.buffer(INIT,MAX);
	    System.out.println(buf.toString());
	    System.out.println(buf.array());
	    
	    runBufOp(buf);
	  
	    
	    buf = Unpooled.directBuffer(INIT,MAX);
	    System.out.println(buf.toString());
	    
	    try{
	        System.out.println(buf.array());
	    }catch(Throwable e){
	    	// java.lang.UnsupportedOperationException: direct buffer
	    	System.out.println(e);
	    }

	    runBufOp(buf);
	    
	    
	    
	    //
	    buf = PooledByteBufAllocator.DEFAULT.buffer(INIT,MAX);
	    runBufOp(buf);
	    
	    
	    buf = PooledByteBufAllocator.DEFAULT.heapBuffer(INIT,MAX);
	    runBufOp(buf);
	    
	    // safe unsafe
	    buf = PooledByteBufAllocator.DEFAULT.directBuffer(INIT,MAX);
	    runBufOp(buf);
		
	}
	
	
	private static String getInfo(ByteBuf buf){
		return buf+",refCnt="+buf.refCnt();
	}
	

	private static void showInfo(ByteBuf buf){
    	System.out.println(getInfo(buf));
	}
	
	
	// 读写操作
	private static void runBufOp(ByteBuf buf){
		
		System.out.println("\n\n*******runBufOp start");
	    showInfo(buf);
		// 写入第一个整数 ， 读索引 0 ，写索引 4
		buf.writeInt(21);
	    showInfo(buf);
	    System.out.println(ByteBufUtil.hexDump(buf));
	    // 读取第一个整数 ，读索引 4 ，写索引 4 
	    int tmp = buf.readInt();
	    System.out.println("int value "+tmp);
	    showInfo(buf);

	    int num = 7;
	    // 写入 0 到 6 ，7个整数 ， 超出容量限制 ，自动扩容
	    for(int i=0;i<num;i++){
			buf.writeInt(i);
		    System.out.println(ByteBufUtil.hexDump(buf));

	    }
	    showInfo(buf);

	    // 写索引 32 ，已达到 最大限制 ，写入失败 
	    try{
	    	buf.writeInt(num);
	    }catch(Throwable e){
	    	// java.lang.IndexOutOfBoundsException: writerIndex(32) + minWritableBytes(4) exceeds maxCapacity(32)
	    	System.out.println(e);
	    }
	    showInfo(buf);

	    // 丢弃已经读取的 ， 会发生复制
	    // 读索引 变为 0 （之前已读取一个整数 读索引4 ）， 写索引 变为28 
	    buf.discardReadBytes();
	    showInfo(buf);
	    // 写索引 28 ，再写入一个数字
	    buf.writeInt(num);
	    showInfo(buf);
	    
	    System.out.println(ByteBufUtil.hexDump(buf));


	    // 连续读取 8个整数 
	    for(int i=0;i<=num;i++){
			System.out.print(buf.readInt()+",");
	    }
	    System.out.println();
	    showInfo(buf);
	    
        // ReferenceCountUtil.release(buf);
	    // showInfo(buf);
	    
	    // 增加 引用计数
	    buf.retain();
	    showInfo(buf);
	    // 释放 引用计数 减1
	    buf.release();
	    showInfo(buf);
	   
	    
        ReferenceCountUtil.release(buf);
	    showInfo(buf);
	    
	    // refCnt 变为 0 时 ，不可用 
        // io.netty.util.IllegalReferenceCountException: refCnt: 0
	    // runBufOp(buf);
	    // io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
	    // ReferenceCountUtil.release(buf);
	    
		System.out.println("*******runBufOp end \n");

	}
	

	
}
